#include "Tps929120.h"
#include "Tps929120_PBCfg.h"


TpsDriver_t  g_stTpsDrivers[DRIVER_CHIP_NUM];
TpsCom_t     g_stUartCom[UART_COM_NUM];


static uint8_t ByteReverse(uint8_t u8Data)
{
	u8Data = ((u8Data & 0x55) <<1) | ((u8Data & 0xAA) >>1);
	u8Data = ((u8Data & 0x33) <<2) | ((u8Data & 0xCC) >>2);
	u8Data = ((u8Data & 0x0F) <<4) | ((u8Data & 0xF0) >>4);
	return u8Data;
}


uint8_t Tps_CrcCalc(uint8_t* pucData, uint16_t usDataLen)
{
	uint8_t u8Loop = 0;
	uint8_t u8Crc = CRC_INIT_VALUE;
	while(usDataLen --)
	{
		u8Crc ^= ByteReverse(*pucData++);
		for(u8Loop=8; u8Loop>0; --u8Loop)
		{
			if(u8Crc & 0x80)
			{
				u8Crc = (u8Crc << 1) ^ CRC_POLY_VALUE;
			}else
			{
				u8Crc = (u8Crc << 1);
			}
		}
	}
	return u8Crc;
}



void Tps_ComEventCallBack(uint8_t u8ComInst, ComEvent_e eEvent)
{
	switch(eEvent)
	{
	case eEvent_SendOneData:
		break;
	case eEvent_RecvOneData:
		break;
	case eEvent_SendComplete:
		if(g_stUartCom[u8ComInst].u8DevInst == INVALID_DEV_INSTANCE)
		{
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
		}else if(g_stTpsDrivers[g_stUartCom[u8ComInst].u8DevInst].u8RxDataLen == 0)
		{
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
			g_stTpsDrivers[g_stUartCom[u8ComInst].u8DevInst] .eDevComState = eIDLE;
			g_stUartCom[u8ComInst].u8DevInst = INVALID_DEV_INSTANCE;
		}
		break;
	case eEvent_RecvComplete:
		if(g_stUartCom[u8ComInst].u8DevInst == INVALID_DEV_INSTANCE){
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
		}else {
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
			g_stTpsDrivers[g_stUartCom[u8ComInst].u8DevInst] .eDevComState = eIDLE;
			g_stUartCom[u8ComInst].u8DevInst = INVALID_DEV_INSTANCE;
		}
		break;
	case eEvent_Idle:
		break;
	case eEvent_Error:
		if(g_stUartCom[u8ComInst].u8DevInst == INVALID_DEV_INSTANCE){
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
		}else {
			g_stUartCom[u8ComInst].eUartComState = eIDLE;
			g_stTpsDrivers[g_stUartCom[u8ComInst].u8DevInst] .eDevComState = eIDLE;
			g_stUartCom[u8ComInst].u8DevInst = INVALID_DEV_INSTANCE;
		}
		break;
	default:
		break;
	}
}



status_t Tps_WriteOneRegBlock(uint8_t u8DevInst, uint8_t u8RegAdd, uint8_t u8Data, uint8_t u8RecvEn)
{
	status_t ret = STATUS_ERROR;
	TpsDriver_t * pstTps = NULL;
	TpsCom_t* pstCom = NULL;
	uint32_t u32TimeoutCnt = 0;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	PARA_ASSERT_RTN((u8RegAdd > REG_ADD_FLAG14),    STATUS_ERROR);
	pstTps = &g_stTpsDrivers[u8DevInst];
	pstCom = &g_stUartCom[pstTps->u8UartComInst];

		pstTps->u8TxBuf[0] = FRMAE_SYNC_BYTE;
		pstTps->u8TxBuf[1] = (u8DevInst | 0x80);

		pstTps->u8TxBuf[2] = u8RegAdd;
		pstTps->u8TxBuf[3] = u8Data;
		pstTps->u8TxBuf[4] = Tps_CrcCalc(&(pstTps->u8TxBuf[1]), 3);
		pstTps->u8TxDataLen = 5;
		if(u8RecvEn == FALSE)
		{
			pstTps->u8RxDataLen = 0;
		}else
		{
			if(pstCom->u8CanPHYFlag)
			{
				pstTps->u8RxDataLen = pstTps->u8TxDataLen + 2;
			}else
			{
				pstTps->u8RxDataLen = 2;
			}

		}

		uartWrite(pstTps->u8TxBuf, pstTps->u8TxDataLen, 0, pstTps->u8RxDataLen);

	return ret;
}



status_t Tps_WriteRegsBlocking(uint8_t u8DevInst, uint8_t u8RegAdd, uint8_t* pu8DataBuf, BurstMode_e eBurstmode, uint8_t u8RecvEn)
{
	status_t ret = STATUS_ERROR;
	TpsDriver_t* pstTps = NULL;
	TpsCom_t* pstCom = NULL;
	uint32_t u32TimeoutCnt = 0;
	uint8_t u8DataLen = 0;
	uint8_t u8Loop = 0;
	uint8_t DATA_LENGTH_x;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	PARA_ASSERT_RTN((u8RegAdd > REG_ADD_FLAG14),    STATUS_ERROR);
	PARA_ASSERT_RTN((eBurstmode > eBurst_8_Byte),   STATUS_ERROR);
	pstTps = &g_stTpsDrivers[u8DevInst];
	pstCom = &g_stUartCom[pstTps->u8UartComInst];

		switch(eBurstmode)
		{
		case eBurst_1_Byte:
			u8DataLen = 1;
			DATA_LENGTH_x = 0x00;
			break;
		case eBurst_2_Byte:
			u8DataLen = 2;
			DATA_LENGTH_x = 0x10;
			break;
		case eBurst_4_Byte:
			u8DataLen = 4;
			DATA_LENGTH_x = 0x20;
			break;
		case eBurst_8_Byte:
			u8DataLen = 8;
			DATA_LENGTH_x = 0x30;
			break;
		default:
			return STATUS_ERROR;
			break;
		}

		pstTps->u8TxBuf[0] = FRMAE_SYNC_BYTE;
		pstTps->u8TxBuf[1] = (u8DevInst | DATA_LENGTH_x | 0x80);


		pstTps->u8TxBuf[2] = u8RegAdd;
		for(u8Loop=0; u8Loop<u8DataLen; u8Loop++)
		{
			pstTps->u8TxBuf[3+u8Loop] = pu8DataBuf[u8Loop];
		}
		pstTps->u8TxBuf[3+u8DataLen] = Tps_CrcCalc(&(pstTps->u8TxBuf[1]), (2+u8DataLen));
		pstTps->u8TxDataLen = 4 + u8DataLen;
		if(u8RecvEn == FALSE)
		{
			pstTps->u8RxDataLen = 0;
		}else
		{
			if(pstCom->u8CanPHYFlag)
			{
				pstTps->u8RxDataLen = pstTps->u8TxDataLen + 2;
			}else
			{
				pstTps->u8RxDataLen = 2;
			}
		}

		uartWrite(pstTps->u8TxBuf, pstTps->u8TxDataLen, 0, pstTps->u8RxDataLen);

	return ret;
}


status_t Tps_WriteRegsBroadcast(uint8_t u8ComInst,uint8_t u8RegAdd, uint8_t* pu8DataBuf, BurstMode_e eBurstmode)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8DataLen = 0;
	uint8_t u8Loop = 0;
	uint32_t u32TimeoutCnt = 0;
	TpsCom_t* pstCom = NULL;
	PARA_ASSERT_RTN((pu8DataBuf == NULL),          STATUS_ERROR);
	PARA_ASSERT_RTN((u8ComInst > UART_COM_NUM),    STATUS_ERROR);
	PARA_ASSERT_RTN((u8RegAdd > REG_ADD_FLAG14),   STATUS_ERROR);
	PARA_ASSERT_RTN((eBurstmode > eBurst_8_Byte),  STATUS_ERROR);
	pstCom = &g_stUartCom[u8ComInst];

		pstCom->u8DevInst = INVALID_DEV_INSTANCE;
		switch(eBurstmode)
		{
		case eBurst_1_Byte:
			u8DataLen = 1;
			break;
		case eBurst_2_Byte:
			u8DataLen = 2;
			break;
		case eBurst_4_Byte:
			u8DataLen = 4;
			break;
		case eBurst_8_Byte:
			u8DataLen = 8;
			break;
		default:
			return STATUS_ERROR;
			break;
		}
		pstCom->u8ComDataBuf[0] = FRMAE_SYNC_BYTE;
		pstCom->u8ComDataBuf[1] = 0;
		DATA_LEN_BIT(pstCom->u8ComDataBuf[1], eBurstmode);
		WR_RD_BIT(pstCom->u8ComDataBuf[1],    WR_RD_WRITE);
		COMM_MODE_BIT(pstCom->u8ComDataBuf[1], COMM_MODE_BROADCAST);
		pstCom->u8ComDataBuf[2] = u8RegAdd;
		for(u8Loop=0; u8Loop<u8DataLen; u8Loop++)
		{
			pstCom->u8ComDataBuf[3+u8Loop] = pu8DataBuf[u8Loop];
		}
		pstCom->u8ComDataBuf[3+u8DataLen] = Tps_CrcCalc(&(pstCom->u8ComDataBuf[1]), (2+u8DataLen));

		uartWrite(pstCom->u8ComDataBuf, 4 + u8DataLen, 0, 4 + u8DataLen);
		ret = STATUS_SUCCESS;

	return ret;
}



status_t Tps_ReadOneRegBlocking(uint8_t u8DevInst, uint8_t u8RegAdd, uint8_t* u8Data)
{
	status_t ret = STATUS_ERROR;
	TpsDriver_t * pstTps = NULL;
	TpsCom_t* pstCom = NULL;
	uint32_t u32TimeoutCnt = 0;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	PARA_ASSERT_RTN((u8RegAdd > REG_ADD_FLAG14),    STATUS_ERROR);
	pstTps = &g_stTpsDrivers[u8DevInst];
	pstCom = &g_stUartCom[pstTps->u8UartComInst];


		pstTps->u8TxBuf[0] = FRMAE_SYNC_BYTE;
		pstTps->u8TxBuf[1] = (u8DevInst | 0x00);

		pstTps->u8TxBuf[2] = u8RegAdd;
		pstTps->u8TxBuf[3] = Tps_CrcCalc(&(pstTps->u8TxBuf[1]), 2);
		pstTps->u8TxDataLen = 4;
		if(pstCom->u8CanPHYFlag)
		{
			pstTps->u8RxDataLen = pstTps->u8TxDataLen + 2;
		}else
		{
			pstTps->u8RxDataLen = 2;
		}

		uartWrite(pstTps->u8TxBuf, pstTps->u8TxDataLen, 1, pstTps->u8TxDataLen+2);

	return ret;
}


status_t Tps_SetChannelEn(uint8_t u8DevInst, uint16_t u16Enbits)
{
	uint8_t u8RegDataBuf[2];
	status_t ret = STATUS_ERROR;
	uint16_t u16ChnlEnBits = u16Enbits;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	u16ChnlEnBits = u16ChnlEnBits & g_stTpsDrivers[u8DevInst].u16ChnlUseMask;
	u8RegDataBuf[0] = (uint8_t)(u16ChnlEnBits & 0xFF);
	u8RegDataBuf[1] = (uint8_t)((u16ChnlEnBits>>8) & 0xF);
	ret = Tps_WriteRegsBlocking(u8DevInst, REG_ADD_CFG_EN0, u8RegDataBuf, eBurst_2_Byte, TRUE);
	if(ret == STATUS_SUCCESS)
	{
		g_stTpsDrivers[u8DevInst].u16ChannelEnbits = (u16ChnlEnBits & 0xFFF);
	}
	return ret;
}



status_t Tps_DisableAllChannel(uint8_t u8DevInst)
{
	status_t ret = STATUS_ERROR;
	ret = Tps_SetChannelEn(u8DevInst, 0);
	return ret;
}



status_t Tps_EnableAllChannel(uint8_t u8DevInst)
{
	status_t ret = STATUS_ERROR;
	ret = Tps_SetChannelEn(u8DevInst, 0xFFF);
	return ret;
}


status_t Tps_BC_SetChannelEn(uint8_t u8ComMask, uint16_t u16Enbits)
{
	status_t ret = STATUS_ERROR;
	uint8_t  u8DevLoop = 0;
	uint8_t  u8ComLoop = 0;
	uint8_t  u8RegDataBuf[2] = {0, 0};
	u8RegDataBuf[0] = (uint8_t)(u16Enbits & 0xFF);
	u8RegDataBuf[1] = (uint8_t)((u16Enbits>>8) & 0xF);
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop) & 0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_EN0, u8RegDataBuf, eBurst_2_Byte);
			if(ret == STATUS_SUCCESS)
			{
				for(u8DevLoop=0; u8DevLoop<DRIVER_CHIP_NUM; u8DevLoop++)
				{
					if(g_stTpsDrivers[u8DevLoop].u8UartComInst == u8ComLoop)
					{
						g_stTpsDrivers[u8DevLoop].u16ChannelEnbits = u16Enbits;
					}
				}
			}
		}
	}
	return ret;
}



status_t Tps_BC_DisableAllChannel()
{
	status_t ret = STATUS_ERROR;
	ret = Tps_BC_SetChannelEn(0xFF, 0);
	return ret;
}



status_t Tps_BC_EnableAllChannel()
{
	status_t ret = STATUS_ERROR;
	ret = Tps_BC_SetChannelEn(0xFF, 0xFFF);
	return ret;
}



status_t Tps_SetPwmReqAndRefRang(uint8_t u8DevInst, uint8_t u8Freq, uint8_t u8RefRang)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData =0;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	u8RegData = (uint8_t)((u8Freq<<4) | (u8RefRang& 0x03));
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC1, u8RegData, TRUE);
	return ret;
}

status_t Tps_BC_SetPwmReqAndRefRang(uint8_t u8ComMask, uint8_t u8Freq, uint8_t u8RefRang)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData =0;
	uint8_t u8ComLoop = 0;
	u8RegData = (uint8_t)((u8Freq<<4) | (u8RefRang& 0x03));
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC1, &u8RegData, eBurst_1_Byte);
		}
	}
	return ret;
}


status_t Tps_SetLock(uint8_t u8DevInst, uint8_t u8LockBits)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM), STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_LOCK, (u8LockBits & 0x0F), TRUE);
	return ret;
}


status_t Tps_BC_SetLock(uint8_t u8ComMask, uint8_t u8LockBits)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData = u8LockBits;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_LOCK, &u8RegData, eBurst_1_Byte);
		}
	}
	return ret;
}


status_t Tps_SetChannelPWMDuty(uint8_t u8DevInst, uint8_t u8ChnlNum, uint16_t u16PwmDuty)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	PARA_ASSERT_RTN((u8ChnlNum >= DRIVER_CHANNEL_NUM), STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_PWMLx(u8ChnlNum), (uint8_t)(u16PwmDuty & 0x0F), TRUE);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_PWMx(u8ChnlNum),  (uint8_t)((u16PwmDuty>>4) & 0xFF), TRUE);
	return ret;
}


status_t Tps_BC_SetChannelPWMDuty(uint8_t u8ComMask, uint8_t u8ChnlNum, uint16_t u16PwmDuty)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8ChnlNum >= DRIVER_CHANNEL_NUM), STATUS_ERROR);
	uint8_t u8ComLoop = 0;
	uint8_t u8DataBuf[2] = {0,0};
	u8DataBuf[0] = (uint8_t)(u16PwmDuty & 0x0F);
	u8DataBuf[1] = (uint8_t)((u16PwmDuty>>4) & 0xFF);
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_PWMLx(u8ChnlNum), &u8DataBuf[0], eBurst_1_Byte);
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_PWMx(u8ChnlNum),  &u8DataBuf[1], eBurst_1_Byte);
		}
	}
	return ret;
}




status_t Tps_SetChannelPWMDutyEn(uint8_t u8DevInst, uint8_t u8ChnlNum, uint16_t u16PwmDuty)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	PARA_ASSERT_RTN((u8ChnlNum >= DRIVER_CHANNEL_NUM), STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_PWMLx(u8ChnlNum), (uint8_t)(u16PwmDuty & 0x0F), TRUE);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_PWMx(u8ChnlNum),  (uint8_t)((u16PwmDuty>>4) & 0xFF), TRUE);
	if(ret != STATUS_SUCCESS)
	{
		return ret;
	}
	if(u16PwmDuty == 0)
	{
		if(g_stTpsDrivers[u8DevInst].u16ChannelEnbits & (1<<u8ChnlNum))
		{
			g_stTpsDrivers[u8DevInst].u16ChannelEnbits &= (~(1<<u8ChnlNum));
			ret = Tps_SetChannelEn(u8DevInst, g_stTpsDrivers[u8DevInst].u16ChannelEnbits);
		}
	}else
	{
		if((g_stTpsDrivers[u8DevInst].u16ChannelEnbits & (1<<u8ChnlNum)) == 0)
		{
			g_stTpsDrivers[u8DevInst].u16ChannelEnbits |= (1<<u8ChnlNum);
			ret = Tps_SetChannelEn(u8DevInst, g_stTpsDrivers[u8DevInst].u16ChannelEnbits);
		}
	}
	return ret;
}


/* bit7: CONF_AUTOSS, bit6: CONF_LDO, bit4: CONF_EXPEN */
status_t Tps_SetMISC0(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC0, u8RegData, TRUE);
	return ret;
}


/* bit7: CONF_AUTOSS, bit6: CONF_LDO, bit4: CONF_EXPEN */
status_t Tps_BC_SetMISC0(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC0, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}


/* bit0~bit3: ADCLowSupplyThreshold , bit4~bit6: uart FilterTimeout */
status_t Tps_SetMISC2(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC2, u8RegData, TRUE);
	return ret;
}

/* bit0~bit3: ADCLowSupplyThreshold , bit4~bit6: uart FilterTimeout */
status_t Tps_BC_SetMISC2(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC2, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}

/* bit4~bit7: Watchdog Timer */
status_t Tps_SetMISC4(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC4, u8RegData, TRUE);
	return ret;
}


/* bit4~bit7: Watchdog Timer */
status_t Tps_BC_SetMISC4(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC4, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}


/*bit0: EEPMODE, bit1: ReadShadow, bit4: SharePWM, bit5:EXTCLK */
status_t Tps_SetMISC7(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC7, u8RegData, TRUE);
	return ret;
}


/*bit0: EEPMODE, bit1: ReadShadow, bit4: SharePWM, bit5:EXTCLK */
status_t Tps_BC_SetMISC7(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC7, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}

status_t Tps_SetMISC8(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CFG_MISC8, u8RegData, TRUE);
	return ret;
}

status_t Tps_BC_SetMISC8(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CFG_MISC8, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}

status_t Tps_SetCLR(uint8_t u8DevInst, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_CLR, u8RegData, TRUE);
	return ret;
}


status_t Tps_BC_SetCLR(uint8_t u8ComMask, uint8_t u8RegData)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8Regdata = u8RegData;
	uint8_t u8ComLoop = 0;
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			ret = Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_CLR, &u8Regdata, eBurst_1_Byte);
		}
	}
	return ret;
}

/* Iout = (CONF_IOUTx + 1) * Ifull_Range / 64*/
status_t Tps_SetIOut(uint8_t u8DevInst, uint8_t u8ChnlNum, uint8_t u8Curr)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData = 0;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	PARA_ASSERT_RTN((u8ChnlNum >= DRIVER_CHANNEL_NUM), STATUS_ERROR);
	if(CHANNEL_CURRENT_MAX <= u8Curr)
	{
		u8RegData = 0x3F;
	}else
	{
		u8RegData = (uint8_t)((uint16_t)u8Curr * 64 / CHANNEL_CURRENT_MAX) + 1;
	}
	ret = Tps_WriteOneRegBlock(u8DevInst, REG_ADD_IOUTx(u8ChnlNum), u8RegData, TRUE);
	return ret;
}

status_t Tps_SetAllIOut(uint8_t u8DevInst, uint8_t u8Curr)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData[DRIVER_CHANNEL_NUM];
	uint8_t u8Loop = 0;
	PARA_ASSERT_RTN((u8DevInst >= DRIVER_CHIP_NUM),    STATUS_ERROR);
	if(CHANNEL_CURRENT_MAX <= u8Curr)
	{
		u8RegData[0] = 0x3F;
	}else
	{
		u8RegData[0] = (uint8_t)((uint16_t)u8Curr * 64 / CHANNEL_CURRENT_MAX) + 1;
	}
	for(u8Loop=1; u8Loop<DRIVER_CHANNEL_NUM; u8Loop++)
	{
		u8RegData[u8Loop] = u8RegData[0];
	}
	ret = Tps_WriteRegsBlocking(u8DevInst, REG_ADD_IOUT0, u8RegData, eBurst_4_Byte, TRUE);
	ret = Tps_WriteRegsBlocking(u8DevInst, REG_ADD_IOUTx(4), &u8RegData[4], eBurst_8_Byte, TRUE);
	return ret;
}


status_t Tps_BC_SetIOut(uint8_t u8ComMask, uint8_t u8ChnlNum, uint8_t u8Curr)
{
	status_t ret = STATUS_ERROR;
	uint8_t u8RegData = 0;
	uint8_t u8ComLoop = 0;
	PARA_ASSERT_RTN((u8ChnlNum >= DRIVER_CHANNEL_NUM), STATUS_ERROR);
	if(CHANNEL_CURRENT_MAX <= u8Curr)
	{
		u8RegData = 0x3F;
	}else
	{
		u8RegData = (uint8_t)((uint16_t)u8Curr * 64 / CHANNEL_CURRENT_MAX) + 1;
	}
	for(u8ComLoop=0; u8ComLoop<UART_COM_NUM; u8ComLoop++)
	{
		if((u8ComMask>>u8ComLoop)&0x01)
		{
			Tps_WriteRegsBroadcast(u8ComLoop, REG_ADD_IOUTx(u8ChnlNum), &u8RegData, eBurst_1_Byte);
		}
	}
	return ret;
}


void Tps_InitVariant()
{
	uint8_t u8Loop = 0;
	for(u8Loop=0; u8Loop<DRIVER_CHIP_NUM; u8Loop++)
	{
		g_stTpsDrivers[u8Loop].eDevComState = eIDLE;
		g_stTpsDrivers[u8Loop].u8DevAddr = 0;
		g_stTpsDrivers[u8Loop].u8RxDataLen = 0;
		g_stTpsDrivers[u8Loop].u8TxDataLen = 0;
		g_stTpsDrivers[u8Loop].u8UartComInst = 0;
		g_stTpsDrivers[u8Loop].u16ChannelEnbits = 0;
		g_stTpsDrivers[u8Loop].u8DevMode = TPS_MODE_INIT;
	}
	for(u8Loop=0; u8Loop<UART_COM_NUM; u8Loop++)
	{
		g_stUartCom[u8Loop].u8DevInst = INVALID_DEV_INSTANCE;
		g_stUartCom[u8Loop].eUartComState = eIDLE;
		g_stUartCom[u8Loop].pfSendData = NULL;
		g_stUartCom[u8Loop].pfReceiveData = NULL;
	}
}


status_t Tps_CfgInit(const TpsCom_UserCfg_t* pstComCfg, uint8_t u8ComCfgNum,
		         const TpsDriver_UserCfg_t* pstTpsCfg, uint8_t DrvCfgNum)
{
	uint8_t u8Loop = 0;
	PARA_ASSERT_RTN((u8ComCfgNum>UART_COM_NUM), STATUS_ERROR);
	PARA_ASSERT_RTN((DrvCfgNum>DRIVER_CHIP_NUM), STATUS_ERROR);
	Tps_InitVariant();
	for(u8Loop=0; u8Loop <u8ComCfgNum; u8Loop++)
	{
		g_stUartCom[u8Loop].pfSendData = pstComCfg[u8Loop].pfSendData;
		g_stUartCom[u8Loop].pfReceiveData = pstComCfg[u8Loop].pfReceiveData;
		g_stUartCom[u8Loop].u8CanPHYFlag = pstComCfg[u8Loop].u8CanPHYFlag;
	}
	for(u8Loop=0; u8Loop <DrvCfgNum; u8Loop++)
	{
		g_stTpsDrivers[u8Loop].u8DevAddr = pstTpsCfg[u8Loop].u8DevAddr;
		g_stTpsDrivers[u8Loop].u8UartComInst = pstTpsCfg[u8Loop].u8UartComInst;
		g_stTpsDrivers[u8Loop].u16ChnlUseMask = pstTpsCfg[u8Loop].u16ChnlUseMask;
	}
	return STATUS_SUCCESS;
}


void Tps_Init(void)
{
	Tps_BC_SetPwmReqAndRefRang(0xFF, PWM_FREQ_7800HZ, REFRANG_512);
	Tps_BC_EnableAllChannel();
	Tps_WriteOneRegBlock(TPS_CHIP_ADD_14, REG_ADD_CFG_DIAGEN0, 0xF, TRUE);	//Enable Diag Register
	Tps_WriteOneRegBlock(TPS_CHIP_ADD_14, REG_ADD_CFG_DIAGEN1, 0x3, TRUE);
	Tps_WriteOneRegBlock(TPS_CHIP_ADD_15, REG_ADD_CFG_DIAGEN0, 0xF, TRUE);	
	Tps_WriteOneRegBlock(TPS_CHIP_ADD_15, REG_ADD_CFG_DIAGEN1, 0x3, TRUE);
	Tps_BC_SetLock(0xFF, 0);
	Tps_BC_SetMISC7(0xFF, 0x00);
	Tps_BC_SetCLR(0xFF, 0x3);
	Tps_BC_SetMISC4(0xFF, 0);
	Tps_BC_SetMISC8(0xFF, 0xC8);
}